﻿using System;
using System.Collections.Generic;
using System.Linq;
using GDM.Hogar.Aplicacion.Formularios;
using GDM.Hogar.Entidades;
using GDM.Hogar.Managers.Contratos;
using Microsoft.Reporting.WinForms;

namespace GDM.Hogar.Aplicacion.Reportes
{
    public partial class FrmReporteEstadisticas
    #if DEBUG
     : AdaptadorFrm
    #else
             : FrmBase
    #endif
    {
        private EstadisticaInscHogar[] estadisticasHogar;
        private EstadisticaInscComedorVianda[] estadisticasComedorVianda;
        private Dictionary<string, EstadisticaInscTalleres> estadisticasTalleres; 
        private readonly IInscripcionManager _inscripcionManager;
        private readonly IActividadManager _actividadManager;

        public FrmReporteEstadisticas(IInscripcionManager inscripcionManager, IActividadManager actividadManager)
        {
            if (inscripcionManager == null)
                throw new ArgumentNullException("inscripcionManager");
            if (actividadManager == null)
                throw new ArgumentNullException("actividadManager");

            _inscripcionManager = inscripcionManager;
            _actividadManager = actividadManager;
            InitializeComponent();
        }

        private void InicializarEstadisticasInstitucion()
        {
            //-Inscriptos en el Hogar
            estadisticasHogar = new EstadisticaInscHogar[3];
            var altas = new EstadisticaInscHogar
            {
                Descripcion = "ALTAS",
                DatoDelMes = new int[11]
            };
            var bajas = new EstadisticaInscHogar
            {
                Descripcion = "BAJAS",
                DatoDelMes = new int[11]
            };
            var totales = new EstadisticaInscHogar
            {
                Descripcion = "TOTAL INSCRIPTOS",
                DatoDelMes = new int[11]
            };
            estadisticasHogar[0] = altas;
            estadisticasHogar[1] = bajas;
            estadisticasHogar[2] = totales;
        }

        private void InicializarEstadisticasComedorVianda()
        {
            //-Inscriptos en Comedor/Vianda
            estadisticasComedorVianda = new EstadisticaInscComedorVianda[4];
            var altasCv = new EstadisticaInscComedorVianda
            {
                Descripcion = "ALTAS",
                DatoComedorDelMes = new int[11],
                DatoViandaDelMes = new int[11],
                TotalDelMes = new int[11]
            };
            var bajasCv = new EstadisticaInscComedorVianda
            {
                Descripcion = "BAJAS",
                DatoComedorDelMes = new int[11],
                DatoViandaDelMes = new int[11],
                TotalDelMes = new int[11]
            };
            var totalCv = new EstadisticaInscComedorVianda
            {
                Descripcion = "TOTAL INSCRIPTOS",
                DatoComedorDelMes = new int[11],
                DatoViandaDelMes = new int[11],
                TotalDelMes = new int[11]
            };
            var asistenciaMediaCv = new EstadisticaInscComedorVianda
            {
                Descripcion = "ASISTENCIA MEDIA",
                DatoComedorDelMes = new int[11],
                DatoViandaDelMes = new int[11],
                TotalDelMes = new int[11]
            };
            estadisticasComedorVianda[0] = altasCv;
            estadisticasComedorVianda[1] = bajasCv;
            estadisticasComedorVianda[2] = totalCv;
            estadisticasComedorVianda[3] = asistenciaMediaCv;
        }

        private void InicializarEstadisticasTalleres()
        {
            //-Inscriptos a talleres
            estadisticasTalleres = new Dictionary<string, EstadisticaInscTalleres>();
        }

        private void InicializarEstadisticas()
        {
            InicializarEstadisticasInstitucion();
            InicializarEstadisticasComedorVianda();
            InicializarEstadisticasTalleres();
        }

        private void CalcularEstadisticasInstitucion()
        {
            //-Inscriptos en el Hogar
            var integrantes = _inscripcionManager.ObtenerInscriptosAlHogar();
            foreach (var integrante in integrantes)
            {
                var mesInscripcion = integrante.FechaInscripcion.Month;
                if (mesInscripcion > 1)
                {
                    estadisticasHogar[0].DatoDelMes[mesInscripcion - 2]++;
                }
                if (integrante.FechaBaja.HasValue)
                {
                    var mesBaja = integrante.FechaBaja.Value.Month;
                    if (mesBaja > 1)
                    {
                        estadisticasHogar[1].DatoDelMes[mesBaja - 2]++;
                    }
                }
            }
            for (var mes = 0; mes < 11; mes++)
            {
                var totalDelMes = estadisticasHogar[0].DatoDelMes[mes] - estadisticasHogar[1].DatoDelMes[mes];
                if (mes == 0) //- Febrero
                {
                    estadisticasHogar[2].DatoDelMes[0] = totalDelMes;
                }
                else
                {
                    //- Calcular el total de inscriptos segun lo del mes anterior
                    estadisticasHogar[2].DatoDelMes[mes] = estadisticasHogar[2].DatoDelMes[mes - 1] + totalDelMes;
                }
            }
        }

        private void CalcularEstadisticasComedorVianda(IEnumerable<ConsultaInscripcion> inscripciones)
        {
            foreach (var inscripcion in inscripciones)
            {
                if (inscripcion.FechaInscripcion.HasValue)
                {
                    var mesInscripcion = inscripcion.FechaInscripcion.Value.Month;
                    if (mesInscripcion > 1)
                    {
                        if (inscripcion.ActividadId == 1)
                        {
                            estadisticasComedorVianda[0].DatoComedorDelMes[mesInscripcion - 2]++;
                        }
                        else
                        {
                            estadisticasComedorVianda[0].DatoViandaDelMes[mesInscripcion - 2]++;
                        }
                    }
                }
                if (inscripcion.FechaBaja.HasValue)
                {
                    var mesBaja = inscripcion.FechaBaja.Value.Month;
                    if (mesBaja > 1)
                    {
                        if (inscripcion.ActividadId == 1)
                        {
                            estadisticasComedorVianda[1].DatoComedorDelMes[mesBaja - 2]++;
                        }
                        else
                        {
                            estadisticasComedorVianda[1].DatoViandaDelMes[mesBaja - 2]++;
                        }
                    }
                }
            }
            for (var mes = 0; mes < 11; mes++)
            {
                //-Comedor
                var totalDelMes = estadisticasComedorVianda[0].DatoComedorDelMes[mes] - estadisticasComedorVianda[1].DatoComedorDelMes[mes];
                if (mes == 0) //- Febrero
                {
                    estadisticasComedorVianda[2].DatoComedorDelMes[0] = totalDelMes;
                }
                else
                {
                    //- Calcular el total de inscriptos segun lo del mes anterior
                    estadisticasComedorVianda[2].DatoComedorDelMes[mes] = estadisticasComedorVianda[2].DatoComedorDelMes[mes - 1] + totalDelMes;
                }

                //-Vianda
                totalDelMes = estadisticasComedorVianda[0].DatoViandaDelMes[mes] - estadisticasComedorVianda[1].DatoViandaDelMes[mes];
                if (mes == 0) //- Febrero
                {
                    estadisticasComedorVianda[2].DatoViandaDelMes[0] = totalDelMes;
                }
                else
                {
                    //- Calcular el total de inscriptos segun lo del mes anterior
                    estadisticasComedorVianda[2].DatoViandaDelMes[mes] = estadisticasComedorVianda[2].DatoViandaDelMes[mes - 1] + totalDelMes;
                }

                //-TotalComedorVianda
                estadisticasComedorVianda[0].TotalDelMes[mes] = estadisticasComedorVianda[0].DatoComedorDelMes[mes] + estadisticasComedorVianda[0].DatoViandaDelMes[mes];
                estadisticasComedorVianda[1].TotalDelMes[mes] = estadisticasComedorVianda[1].DatoComedorDelMes[mes] + estadisticasComedorVianda[1].DatoViandaDelMes[mes];
                estadisticasComedorVianda[2].TotalDelMes[mes] = estadisticasComedorVianda[2].DatoComedorDelMes[mes] + estadisticasComedorVianda[2].DatoViandaDelMes[mes];
            }
        }

        private void ActualizarDatosTaller(EstadisticaInscTalleres estadisticasTaller, ConsultaInscripcion inscripcion)
        {
            if (inscripcion.FechaInscripcion.HasValue)
            {
                var mesInscripcion = inscripcion.FechaInscripcion.Value.Month;
                if (mesInscripcion > 2)
                {
                    estadisticasTaller.Altas[mesInscripcion - 3]++;
                }
            }
            if (inscripcion.FechaBaja.HasValue)
            {
                var mesBaja = inscripcion.FechaBaja.Value.Month;
                if (mesBaja > 2)
                {
                    estadisticasTaller.Bajas[mesBaja - 3]++;
                }
            }
        }

        private void CalcularEstadisticasTalleres(IEnumerable<ConsultaInscripcion> inscripciones)
        {
            foreach (var inscripcion in inscripciones)
            {
                EstadisticaInscTalleres estadisticasTaller;
                estadisticasTalleres.TryGetValue(inscripcion.Actividad, out estadisticasTaller);
                if (estadisticasTaller != null)
                {
                    ActualizarDatosTaller(estadisticasTaller, inscripcion);
                }
                else
                {
                    estadisticasTaller = new EstadisticaInscTalleres
                    {
                        Nombre = inscripcion.Actividad,
                        Altas = new int[10],
                        Bajas = new int[10],
                        Inscripciones = new int[10],
                        AsistenciaMedia = new int[10]
                    };
                    ActualizarDatosTaller(estadisticasTaller, inscripcion);
                    estadisticasTalleres.Add(inscripcion.Actividad, estadisticasTaller);
                }
            }
            foreach (var estadisticaTaller in estadisticasTalleres.Values)
            {
                for (var mes = 0; mes < 10; mes++)
                {
                    var totalDelMes = estadisticaTaller.Inscripciones[mes] = estadisticaTaller.Altas[mes] - estadisticaTaller.Bajas[mes];
                    if (mes == 0) //- Marzo
                    {
                        estadisticaTaller.Inscripciones[0] = totalDelMes;
                    }
                    else
                    {
                        //- Calcular el total de inscriptos segun lo del mes anterior
                        estadisticaTaller.Inscripciones[mes] = estadisticaTaller.Inscripciones[mes - 1] + totalDelMes;
                    }
                }
            }
        }

        private void CalcularEstadisticas()
        {
            var inscripciones = _actividadManager.ObtenerInscripciones();

            //-Inscriptos en el Hogar
            CalcularEstadisticasInstitucion();
            //-Inscriptos en Comedor/Vianda
            CalcularEstadisticasComedorVianda(inscripciones.Where(x => x.ActividadId == 1 || x.ActividadId == 2));
            //-Inscriptos en talleres
            CalcularEstadisticasTalleres(inscripciones.Where(x => x.ActividadId > 2).OrderBy(x => x.Actividad));
        }

        private void FrmReporteEstadisticas_Load(object sender, EventArgs e)
        {
            InicializarEstadisticas();
            CalcularEstadisticas();
            rpEstadisticas.Messages = new MensajesReportViewer();
            rpEstadisticas.LocalReport.SetParameters(new ReportParameter("NombreInstitucion", "El Hornero"));
            rpEstadisticas.LocalReport.DataSources.Clear();
            var datosInstitucion = estadisticasHogar.ToList();
            var datosComedorVianda = estadisticasComedorVianda.ToList();
            var datosTalleres = estadisticasTalleres.Values.ToList();
            const int cantTalleresPorPagina = 16;
            var cantPaginas = datosTalleres.Count / cantTalleresPorPagina + 1;
            var totalACompletar = (cantPaginas * cantTalleresPorPagina) - datosTalleres.Count;
            for (var i = 0; i < totalACompletar; i++)
            {
                datosTalleres.Add(new EstadisticaInscTalleres
                {
                    Altas = new int[10],
                    Bajas = new int[10],
                    Inscripciones = new int[10],
                    AsistenciaMedia = new int[10]
                });
            }
            rpEstadisticas.LocalReport.DataSources.Add(new ReportDataSource("InscriptosInstitucion_DS", datosInstitucion));
            rpEstadisticas.LocalReport.DataSources.Add(new ReportDataSource("DemandaPendiente_DS", new List<EmptySource>{new EmptySource()}));
            rpEstadisticas.LocalReport.DataSources.Add(new ReportDataSource("InscriptosComedorVianda_DS", datosComedorVianda));
            rpEstadisticas.LocalReport.DataSources.Add(new ReportDataSource("InscriptosTalleres_DS", datosTalleres));
            rpEstadisticas.RefreshReport();
        }
    }
}
